﻿using Microsoft.Win32;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using MysToolCore;
using Path = System.IO.Path;
using FileManager.ViewModel;
using FileManager.Model;
using System.Runtime.InteropServices;
using System.Windows.Shapes;
using CheckBox = System.Windows.Controls.CheckBox;
using FileManager.MyProcess;

namespace FileManager
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // 定义常量
        const int WM_COMMAND = 0x0111;
        [DllImport("user32.dll")]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll")]
        static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
        private static Dictionary<string, List<FileInfo>> fileDic = new Dictionary<string, List<FileInfo>>();

        private List<string> fileNames = new List<string>();

        private static List<string> tagList = new();

        private MainWindowViewModel model { get; set; }
        public MainWindow()
        {
            InitializeComponent();
            // 在程序启动的某个地方  
            System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);

            model = new MainWindowViewModel(this) { Idx = 0 };
            DataContext = model;
        }


        public void Update()
        {
            var fileInfos = model.Meta2Show;
            if (fileInfos.Count <= 0)
                return;
            if(model.ShowAll)
            {
                fileNames = fileInfos.Select(a => a.Path).ToList() ;
                model.Idx = 0;
                model.MaxNum = 1;
                lbFiles.ItemsSource = fileNames;
                return;
            }

            model.CurrentFile = fileInfos[model.Idx];
            lbFiles.ItemsSource = new List<string>() { model.CurrentFile.Path };
            foreach (CheckBox check in CheckBoxPanel.Children)
            {
                check.IsChecked = false;
            }
            foreach (var tag in model.CurrentFile.Tag)
            {
                CheckBox newCheckBox = new CheckBox();
                if (tagList.Contains(tag))
                {
                    foreach (CheckBox check in CheckBoxPanel.Children)
                    {
                        if (check.Content.ToString() == tag)
                        {
                            check.IsChecked = true;
                        }
                    }
                    continue;
                }
                tagList.Add(tag);
                // 设置CheckBox的属性
                newCheckBox.Content = tag; // 设置显示的文本
                newCheckBox.IsChecked = true; // 设置初始状态为未选中
                newCheckBox.Margin = new Thickness(5, 5, 5, 5);
                CheckBoxPanel.Children.Add(newCheckBox);
            }
        }
        
        public void AddCheckBox(string tag)
        {
            if (tagList.Contains(tag))
                return;
            CheckBox newCheckBox = new CheckBox();
            tagList.Add(tag);
            // 设置CheckBox的属性
            newCheckBox.Content = tag; // 设置显示的文本
            newCheckBox.IsChecked = false; // 设置初始状态为未选中
            newCheckBox.Margin = new Thickness(5, 5, 5, 5);
            newCheckBox.Width = 70;
            CheckBoxPanel.Children.Add(newCheckBox);
        }
        private static void copyFiles(List<string> allFiles, string saveRoot)
        {
            foreach (var file in allFiles)
            {
                string desPath = Path.Combine(saveRoot, new FileInfo(file).Name);
                if (!File.Exists(desPath))
                {
                    File.Copy(file, desPath);
                }
            }
        }

        private static Dictionary<string, List<FileInfo>> GetSameFile(ICollection<string> filePaths)
        {
            Dictionary<string, List<FileInfo>> fileHashes = new Dictionary<string, List<FileInfo>>();
            foreach (var file in filePaths)
            {
                using (var sha1 = System.Security.Cryptography.SHA512.Create())
                {
                    using (var stream = File.OpenRead(file))
                    {
                        var hashBytes = sha1.ComputeHash(stream);
                        var hash = BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
                        var v = fileHashes.GetOrAdd(hash, new List<FileInfo>(), a => a == null || a.Count == 0);
                        v.Add(new FileInfo(file));
                    }
                }
            }
            return fileHashes.Where(a => a.Value.Count > 1).ToDictionary();
        }

        public static List<string> TraverseAndPrintFiles(string directoryPath)
        {
            List<string> allFiles = new List<string>();
            foreach (string filePath in Directory.GetFiles(directoryPath, "*", SearchOption.AllDirectories))
            {
                allFiles.Add(filePath);
                //Debug.WriteLine(filePath);
            }
            return allFiles;
        }

        private void BtnAdd_Click(object sender, RoutedEventArgs e)
        {
            // 创建CheckBox实例
            CheckBox newCheckBox = new CheckBox();
            string tag = tagText.Text.Trim();
            if (tagList.Contains(tag))
                return;
            tagList.Add(tag);
            // 设置CheckBox的属性
            newCheckBox.Content = tag; // 设置显示的文本
            newCheckBox.IsChecked = true; // 设置初始状态为未选中
            newCheckBox.Margin = new Thickness(5, 5, 5, 5);
            CheckBoxPanel.Children.Add(newCheckBox);
        }

        private void BtnImp_Click(object sender, RoutedEventArgs e)
        {
            OpenFolderDialog openFolderDialog = new OpenFolderDialog();
            if (!openFolderDialog.ShowDialog().HasValue)
                return;
            string folderPath = openFolderDialog.FolderName;
            var allFiles = TraverseAndPrintFiles(folderPath);
            var oriFiles = FileMetadataCollection.FromEnumerable(from file in allFiles select new MetaData(file));
            DirectoryInfo dir = new DirectoryInfo(folderPath);
            string path=Path.Combine(dir.Name + ".xml");
            FileMetadataUtils.SaveToFile(oriFiles, path);
        }


        private void BtnOpen_Click(object sender, RoutedEventArgs e)
        {
            if (lbFiles.SelectedIndex != -1)
            {
                string? selectedFile = lbFiles.SelectedItem as string;
                if (null != selectedFile)
                {
                    string wpsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "kingsoft", "WPS Office\\\\ksolaunch.exe");

                    string wpsAppPath = null;
                    string fileExtension = Path.GetExtension(selectedFile).ToLower();

                    if (File.Exists(wpsPath) && (fileExtension == ".doc" || fileExtension == ".docx" || fileExtension == ".dot" || fileExtension == ".dotx" || fileExtension == ".pdf"))
                    {
                        wpsAppPath = wpsPath;
                    }
                    else if (File.Exists(wpsPath) && (fileExtension == ".xls" || fileExtension == ".xlsx" || fileExtension == ".xlt" || fileExtension == ".xltx"))
                    {
                        wpsAppPath = wpsPath;
                    }
                    else if (File.Exists(wpsPath) && (fileExtension == ".ppt" || fileExtension == ".pptx" || fileExtension == ".pot" || fileExtension == ".potx"))
                    {
                        wpsAppPath = wpsPath;
                    }

                    if (wpsAppPath != null)
                    {
                        // 使用 WPS 打开文件
                        Process.Start(new ProcessStartInfo(wpsAppPath, $"\"{selectedFile}\""));
                    }
                    if (model.OpenDir)
                    {
                        string directoryPath = Path.GetDirectoryName(selectedFile);
                        string dirPathName = directoryPath.Split('\\').Last();
                        // 构建命令字符串，打开文件夹并尝试选中文件
                        string command = $"/select,\"{selectedFile.Replace("\"", "\"\"")}\""; // 对路径中的双引号进行转义

                        // 判断当前活动窗口标题是否包含文件所在目录路径，以判断资源管理器是否已打开该文件夹
                        bool isExplorerOpenInDirectory = Process.GetProcesses()
                            .Where(p => !string.IsNullOrEmpty(p.MainWindowTitle))
                            .Any(p => p.MainWindowTitle.Contains(dirPathName));

                        //if (!isExplorerOpenInDirectory)
                        {
                            // 资源管理器未打开该文件夹，直接启动新进程打开并选中文件
                            Process.Start("explorer.exe", command);
                        }
                        //else
                        {
                            // 资源管理器已打开该文件夹，发送WM_COMMAND消息以选中文件
                            IntPtr hWnd = FindWindow("CabinetWClass", null); // 获取资源管理器主窗口句柄
                            if (hWnd != IntPtr.Zero)
                            {
                                SendMessage(hWnd, WM_COMMAND, new IntPtr(0x115), (IntPtr)selectedFile.GetHashCode()); // 选中文件
                            }
                        }
                    }
                }
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            OpenFolderDialog openFolderDialog = new OpenFolderDialog();
            if (!openFolderDialog.ShowDialog().HasValue)
                return;
            string folderPath = openFolderDialog.FolderName;
            var allFiles = TraverseAndPrintFiles(folderPath);
            openFolderDialog.Title = "请选择保存文件夹";
            if (!openFolderDialog.ShowDialog().HasValue)
                return;
            string saveRoot = openFolderDialog.FolderName;

            copyFiles(allFiles, saveRoot);
            //GetSameFile(allFiles, saveRoot);
        }
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            OpenFolderDialog openFolderDialog = new OpenFolderDialog();
            if (!openFolderDialog.ShowDialog().HasValue)
                return;
            string folderPath = openFolderDialog.FolderName;
            var allFiles = TraverseAndPrintFiles(folderPath);
            fileDic = GetSameFile(allFiles);
            model.Idx = 0;
            model.MaxNum = fileDic.Count;
            if (model.Idx != 0)
            {
                fileNames = fileDic.ElementAt(model.Idx).Value.Select(a => a.FullName).ToList();
                lbFiles.ItemsSource = fileNames;
                proBar.Maximum = fileDic.Count;
                proBar.Value = model.Idx;
            }
        }
        private void slide_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            Debug.WriteLine(model.Idx);
        }

        private void lbFiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lbFiles.SelectedIndex != -1 || lbFiles.Items.Count == 1)
            {
                string selectedFile = null;
                if (lbFiles.Items.Count == 1)
                    selectedFile = (string)lbFiles.Items[0] as string;
                else
                {
                    selectedFile = lbFiles.SelectedItem as string;
                }
                if (selectedFile == null)
                    return;
                var file = model.oriFiles.First(a => a.Path == selectedFile);
                model.CurrentFile = file;
                model.FileDetal = "";
                //if (file != null&&Path.Exists(file.Path))
                //{
                //    model.FileDetal = $"文件名称：{file.FileName}，修改时间：{file.LastWriteTime.ToString("yy-MM-dd HH:mm:ss-FF")}";
                //}
            }
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            BookWindow bookWindow = new BookWindow();
            bookWindow.ShowDialog();
        }

        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            Demo demo= new Demo();
            demo.Fire(Demo.Trigger.拨打电话);
            //demo.Fire(Demo.Trigger.我有事);
            demo.Fire(Demo.Trigger.知道了);
            

        }
    }
}